home *** CD-ROM | disk | FTP | other *** search
/ SGI Freeware 2002 November / SGI Freeware 2002 November - Disc 3.iso / dist / fw_qt3.idb / usr / freeware / Qt / tutorial / t11 / cannon.cpp.z / cannon.cpp
C/C++ Source or Header  |  2002-04-08  |  3KB  |  157 lines

  1. /****************************************************************
  2. **
  3. ** Implementation CannonField class, Qt tutorial 11
  4. **
  5. ****************************************************************/
  6.  
  7. #include "cannon.h"
  8. #include <qtimer.h>
  9. #include <qpainter.h>
  10. #include <qpixmap.h>
  11.  
  12. #include <math.h>
  13.  
  14.  
  15. CannonField::CannonField( QWidget *parent, const char *name )
  16.         : QWidget( parent, name )
  17. {
  18.     ang = 45;
  19.     f = 0;
  20.     timerCount = 0;
  21.     autoShootTimer = new QTimer( this, "movement handler" );
  22.     connect( autoShootTimer, SIGNAL(timeout()),
  23.          this, SLOT(moveShot()) );
  24.     shoot_ang = 0;
  25.     shoot_f = 0;
  26.     setPalette( QPalette( QColor( 250, 250, 200) ) );
  27. }
  28.  
  29.  
  30. void CannonField::setAngle( int degrees )
  31. {
  32.     if ( degrees < 5 )
  33.     degrees = 5;
  34.     if ( degrees > 70 )
  35.     degrees = 70;
  36.     if ( ang == degrees )
  37.     return;
  38.     ang = degrees;
  39.     repaint( cannonRect(), FALSE );
  40.     emit angleChanged( ang );
  41. }
  42.  
  43.  
  44. void CannonField::setForce( int newton )
  45. {
  46.     if ( newton < 0 )
  47.     newton = 0;
  48.     if ( f == newton )
  49.     return;
  50.     f = newton;
  51.     emit forceChanged( f );
  52. }
  53.  
  54.  
  55. void CannonField::shoot()
  56. {
  57.     if ( autoShootTimer->isActive() )
  58.     return;
  59.     timerCount = 0;
  60.     shoot_ang = ang;
  61.     shoot_f = f;
  62.     autoShootTimer->start( 50 );
  63. }
  64.  
  65.  
  66. void CannonField::moveShot()
  67. {
  68.     QRegion r( shotRect() );
  69.     timerCount++;
  70.  
  71.     QRect shotR = shotRect();
  72.  
  73.     if ( shotR.x() > width() || shotR.y() > height() )
  74.     autoShootTimer->stop();
  75.     else
  76.     r = r.unite( QRegion( shotR ) );
  77.     repaint( r );
  78. }
  79.  
  80.  
  81. void CannonField::paintEvent( QPaintEvent *e )
  82. {
  83.     QRect updateR = e->rect();
  84.     QPainter p( this );
  85.  
  86.     if ( updateR.intersects( cannonRect() ) )
  87.     paintCannon( &p );
  88.     if ( autoShootTimer->isActive() &&
  89.      updateR.intersects( shotRect() ) )
  90.     paintShot( &p );
  91. }
  92.  
  93.  
  94. void CannonField::paintShot( QPainter *p )
  95. {
  96.     p->setBrush( black );
  97.     p->setPen( NoPen );
  98.     p->drawRect( shotRect() );
  99. }
  100.  
  101.  
  102. const QRect barrelRect(33, -4, 15, 8);
  103.  
  104. void CannonField::paintCannon( QPainter *p )
  105. {
  106.     QRect cr = cannonRect();
  107.     QPixmap pix( cr.size() );
  108.     pix.fill( this, cr.topLeft() );
  109.  
  110.     QPainter tmp( &pix );
  111.     tmp.setBrush( blue );
  112.     tmp.setPen( NoPen );
  113.  
  114.     tmp.translate( 0, pix.height() - 1 );
  115.     tmp.drawPie( QRect( -35,-35, 70, 70 ), 0, 90*16 );
  116.     tmp.rotate( -ang );
  117.     tmp.drawRect( barrelRect );
  118.     tmp.end();
  119.  
  120.     p->drawPixmap( cr.topLeft(), pix );
  121. }
  122.  
  123.  
  124. QRect CannonField::cannonRect() const
  125. {
  126.     QRect r( 0, 0, 50, 50 );
  127.     r.moveBottomLeft( rect().bottomLeft() );
  128.     return r;
  129. }
  130.  
  131.  
  132. QRect CannonField::shotRect() const
  133. {
  134.     const double gravity = 4;
  135.  
  136.     double time      = timerCount / 4.0;
  137.     double velocity  = shoot_f;
  138.     double radians   = shoot_ang*3.14159265/180;
  139.  
  140.     double velx      = velocity*cos( radians );
  141.     double vely      = velocity*sin( radians );
  142.     double x0        = ( barrelRect.right()  + 5 )*cos(radians);
  143.     double y0        = ( barrelRect.right()  + 5 )*sin(radians);
  144.     double x         = x0 + velx*time;
  145.     double y         = y0 + vely*time - 0.5*gravity*time*time;
  146.  
  147.     QRect r = QRect( 0, 0, 6, 6 );
  148.     r.moveCenter( QPoint( qRound(x), height() - 1 - qRound(y) ) );
  149.     return r;
  150. }
  151.  
  152.  
  153. QSizePolicy CannonField::sizePolicy() const
  154. {
  155.     return QSizePolicy( QSizePolicy::Expanding, QSizePolicy::Expanding );
  156. }
  157.